#ifndef __UDSF_RAMP_C__
#define __UDSF_RAMP_C__

#include "app.h"
/*
*   notice:
*   UDSF 同UDF编程：不可调用cstd-lib,只可调用"sdk_ifs_udk_cfg.h"、"sys_api.h"中列出的API函数。
*   UDSF文件内函数均需使用static修饰符，且UDF中以#include "udsf_xxx.c"形式引用
*/

#include "../udsf/udsf_gpio.c"

#if !defined(USE_EX_RF)
static uint32_t udsf_ramp_reg_gene(uint8_t direction,uint16_t bw_mhz,uint16_t t_us,uint8_t width_id) __attribute__((unused));
static void udsf_ramp_perf_param_get(uint32_t low_st,uint32_t low_end,uint32_t high_st,uint32_t high_end,uint32_t *pll_start,uint32_t*p_pll_end) __attribute__((unused));
static void udsf_ramp_vctrl_enable(void) __attribute__((unused));
static void udsf_ramp_test(void) __attribute__((unused));

/* 仅可用于40M频率 ramp寄存器生成，可靠性未完全验证*/
static uint32_t udsf_ramp_reg_gene(uint8_t direction,uint16_t bw_mhz,uint16_t t_us,uint8_t width_id){
	uint32_t tmp = 250000*bw_mhz/t_us;
	uint16_t reg = 0;
	uint32_t u32_reg;

	for( int i=0;i<15;i++){
		if( tmp >  100000000 ){
			tmp -= 100000000;
			reg |= 1<<(14-i);
		}
		tmp*=2;
	}
	if( direction ){
		reg |= 1<<15;
	}
	u32_reg = (reg<<16) + t_us*20 + width_id;

	return u32_reg;
}

static void udsf_ramp_perf_param_get(uint32_t low_st,uint32_t low_end,uint32_t high_st,uint32_t high_end,uint32_t *pll_start,uint32_t*p_pll_end) __attribute__((unused));

static void udsf_ramp_vctrl_enable(void){
	paramANA_Venus->ana2.ana_cfg1 &= (~(3<<29));
	paramANA_Venus->ana2.ana_cfg1 |= (3<<22);
	paramANA_Venus->ana2.ana_cfg1 |= (1<<19);
	
	udsf_gpio_output_ctrl(1<<4,0);
	udsf_pinctrl_ue(1<<4,0);
	udsf_pinctrl_re(1<<4,0);
	udsf_pinctrl_ae(1<<4,1);
}
static void udsf_ramp_perf_param_get(uint32_t low_st,uint32_t low_end,uint32_t high_st,uint32_t high_end,uint32_t *p_pll_start,uint32_t*p_pll_end){

	uint32_t bk_ramp_wm_cfg0  =  paramANA_Venus->ramp_wm_cfg0;
	uint32_t ramp_mem03 = paramANA_Venus->ramp_mem03;
	uint32_t ramp_mem02 = paramANA_Venus->ramp_mem02;
	uint32_t ramp_mem01 = paramANA_Venus->ramp_mem01;
	uint32_t ramp_mem00 = paramANA_Venus->ramp_mem00;
	uint32_t ana2_cfg2  = paramANA_Venus->ana2.ana_cfg2;
	
	paramANA_Venus->ramp_wm_cfg0    = UDP_CFG_RAMP_WAVE0_INF;     //circle mode
	paramANA_Venus->ramp_mem03      = RAMP_GET(RAMP_0G_10US);   //A: 100us     0G  
	paramANA_Venus->ramp_mem02      = RAMP_GET(RAMP_0G_10US),   //B: 100us     0G
	paramANA_Venus->ramp_mem01      = RAMP_GET(RAMP_0G_10US),   //c: 100us     0G
	paramANA_Venus->ramp_mem00      = 0x00000000 + (1<<16),

	// udsf_ramp_vctrl_enable();  // vco输出至gpio0.4
	paramANA_Venus->ana2.ana_cfg2 &= (~0x7E);
	paramANA_Venus->ana2.ana_cfg2 |= 0x60;   // sta0 vco超限标识 阈值 00/01/10/11
	
	ANACFG_SET(&paramANA_Venus->ana2);
	
	uint32_t ramp_pll_min=0;
	uint32_t ramp_pll_max=0;
	
	uint32_t start = (low_st - 20480)/10; // 23000M起
	uint32_t end   = (low_end - 20480)/10; // 23500M止
	

	for( int i=start;i<end;i+=1){ // 10M步进
		WDT->STR = 1;
		paramANA_Venus->ramp_pll_cfg = i<<16;
		RF_VENUS_INIT();
		ana_Venus_st->ramp_cmd = VENUS_WAVE_START;       // sweep start
		int flag = 0;
		for( int j=0;j<20;j++ ){
			udsf_delay_us(10);
			if( ana_Venus_st->sys_sta0 & 0x40 ){
				flag = 1;
			}
		}
		
		RF_VENUS_DEINIT();
		
		if( !flag ){
			ramp_pll_min = i*10 + 20480;
			break;
		}
	}
	
	
	start = (high_st  - 20480)/10;  // 24900M起
	end =   (high_end - 20480)/10;  // 25400M止
	
	for( int i=start;i<end;i+=1){ // 10M步进
		WDT->STR = 1;
		paramANA_Venus->ramp_pll_cfg = i<<16;
		RF_VENUS_INIT();
		ana_Venus_st->ramp_cmd = VENUS_WAVE_START;       // sweep start
		int flag = 0;
		for( int j=0;j<20;j++ ){
			udsf_delay_us(10);
			if( ana_Venus_st->sys_sta0 & 0x80 ){
				flag = 1;
			}
		}
		RF_VENUS_DEINIT();
		if( flag ){
			ramp_pll_max = i*10 + 20480;
			break;
		}
	}
	
	*p_pll_start = ramp_pll_min;
	*p_pll_end   = ramp_pll_max;
	
	ANACFG_SET(&paramANA_Venus->ana1);
	
	paramANA_Venus->ramp_wm_cfg0          =      bk_ramp_wm_cfg0;
	paramANA_Venus->ramp_mem03            =      ramp_mem03;
	paramANA_Venus->ramp_mem02            =      ramp_mem02;
	paramANA_Venus->ramp_mem01            =      ramp_mem01;
	paramANA_Venus->ramp_mem00            =      ramp_mem00;
	paramANA_Venus->ana2.ana_cfg2         =      ana2_cfg2;
}
#if 0
static void udsf_ramp_test(void){
	
	paramANA_Venus->ramp_wm_cfg0    = UDP_CFG_RAMP_WAVE0_WAVE1_INF;        //circle mode
	
	paramANA_Venus->ramp_mem03      = RAMP_GET(RAMP_0G_100US);   //A: 100us     0G  
	paramANA_Venus->ramp_mem02      = RAMP_GET(RAMP_0G_100US),   //B: 100us     0G
	paramANA_Venus->ramp_mem01      = RAMP_GET(RAMP_0G_100US),   //c: 100us     0G
	paramANA_Venus->ramp_mem00      = 0x00000000 + (1<<16),
	
	paramANA_Venus->ramp_mem13      = RAMP_GET(RAMP_0G_100US)+1, //A: 100us     0G
	paramANA_Venus->ramp_mem12      = RAMP_GET(RAMP_0G_100US),   //B: 100us     0G
	paramANA_Venus->ramp_mem11      = RAMP_GET(RAMP_0G_100US),   //c: 100us     0G
	paramANA_Venus->ramp_mem10      = 0x00000000 + (1<<16),

	udsf_ramp_vctrl_enable();  // vco输出至gpio0.4
	paramANA_Venus->ana2.ana_cfg2 &= (~0x7E);
	paramANA_Venus->ana2.ana_cfg2 |= 0x60;   // sta0 vco超限标识 阈值 00/01/10/11
	ANACFG_SET(&paramANA_Venus->ana2);
	
	uint32_t ramp_pll_min;
	uint32_t ramp_pll_max;
	uint32_t ramp_pll_max_last;
	
	for( int i=0xF0;i<0x200;i++){ // 22.880G ~ 25.600G
		WDT->STR = 1;
		
		paramANA_Venus->ramp_pll_cfg = i<<16; // 10Mhz步进 单频点
		RF_VENUS_INIT();
		ana_Venus_st->ramp_cmd = VENUS_WAVE_START;       // sweep start
		
		int max_error = 0;
		for( int j=0;j<20;j++ ){
			udsf_delay_ms(10);
			uint32_t xx = paramANA_Venus->ramp_pll_cfg;
			udsf_uart_send_u32_base16(1,&xx,1,"pll cfg:","");
			xx = 20480+10*i;
			udsf_uart_send_u32_base16(1,&xx,1,"(","Mhz)");
			xx=ana_Venus_st->sys_sta0;
			udsf_uart_send_u32_base16(1,&xx,1,"\t\tramp sta:","\n");
			if( ana_Venus_st->sys_sta0 & 0x40 ){
				ramp_pll_min = paramANA_Venus->ramp_pll_cfg;
			}
			
			if( !(ana_Venus_st->sys_sta0 & 0x80) ){
				ramp_pll_max = paramANA_Venus->ramp_pll_cfg;
			}else{
				max_error = 1;
			}
		}

		if( max_error ){
			ramp_pll_max = ramp_pll_max_last;
		}
		ramp_pll_max_last = ramp_pll_max;
		
		RF_VENUS_DEINIT();
	}
	ramp_pll_min = ((ramp_pll_min+1 >>16))<<16;
	ramp_pll_max = ((ramp_pll_max >>16))<<16;
	
	while(1){
		WDT->STR = 1;
		
		paramANA_Venus->ramp_pll_cfg = ramp_pll_min;
		RF_VENUS_INIT();
		ana_Venus_st->ramp_cmd = VENUS_WAVE_START;       // sweep start
		udsf_uart_send_u32_base16(1,&ramp_pll_min,1,"ramp pll min:","");
		
		uint32_t xx = 20480+(ramp_pll_min>>16)*10;
		udsf_uart_send_u32_base16(1,&xx,1,"(","Mhz)");
		udsf_delay_ms(2500);
		WDT->STR = 1;
		udsf_delay_ms(2500);
		WDT->STR = 1;
		xx=ana_Venus_st->sys_sta0;
		udsf_uart_send_u32_base16(1,&xx,1,"\t\tramp sta:","\n");
		RF_VENUS_DEINIT();
		
		paramANA_Venus->ramp_pll_cfg = ramp_pll_max;
		RF_VENUS_INIT();
		ana_Venus_st->ramp_cmd = VENUS_WAVE_START;       // sweep start
		udsf_uart_send_u32_base16(1,&ramp_pll_max,1,"ramp pll max:","");
		xx = 20480+(ramp_pll_max>>16)*10;
		udsf_uart_send_u32_base16(1,&xx,1,"(","Mhz)");
		
		udsf_delay_ms(2500);
		WDT->STR = 1;
		udsf_delay_ms(2500);
		WDT->STR = 1;
		xx=ana_Venus_st->sys_sta0;
		udsf_uart_send_u32_base16(1,&xx,1,"\t\tramp sta:","\n");
		RF_VENUS_DEINIT();
	}

//ANA_CFG2 bit6:bit1 0b000000
//ramp pll min:00 FA 00 00 (22.98Ghz)		ramp sta:00 00 00 03   VCO 电压 0.213V
//ramp pll max:01 F7 00 00 (25.51Ghz)		ramp sta:00 00 00 03   VCO 电压 1.006V

//ANA_CFG2 bit6:bit1 0b010000
//ramp pll min:01 07 00 00 (23.11Ghz)		ramp sta:00 00 00 03  VCO电压 0.259V
//ramp pll max:01 EA 00 00 (25.38Ghz)		ramp sta:00 00 00 03  VCO电压 0.946V

//ANA_CFG2 bit6:bit1 0b100000
//ramp pll min:01 15 00 00 (23.25Ghz)		ramp sta:00 00 00 03  VCO电压 0.306V
//ramp pll max:01 DF 00 00 (25.27Ghz)		ramp sta:00 00 00 03  VCO电压 0.901V

//ANA_CFG2 bit6:bit1 0b110000
//ramp pll min:01 23 00 00 (23.39Ghz)		ramp sta:00 00 00 03  VCO电压 0.348V
//ramp pll max:01 D5 00 00 (25.17Ghz)		ramp sta:00 00 00 03  VCO电压 0.863V
}

#endif

#endif

#endif
